// SHLineGraphView.m
//
// Copyright (c) 2014 Shan Ul Haq (http://grevolution.me)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#import "SHLineGraphView.h"
#import "PopoverView.h"
#import "SHPlot.h"
#import <math.h>
#import <objc/runtime.h>

/**数量*/
//#define INTERVAL_COUNT 9

#define kAssociatedPlotObject @"kAssociatedPlotObject"

@implementation SHLineGraphView

- (instancetype)init {
    if((self = [super init])) {
        [self loadDefaultTheme];
    }
    return self;
}

- (void)awakeFromNib{
    [self loadDefaultTheme];
}

- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self loadDefaultTheme];
    }
    return self;
}

- (void)loadDefaultTheme {
    _themeAttributes = @{
                         kXAxisLabelColorKey : [UIColor colorWithRed:0.48 green:0.48 blue:0.49 alpha:0.4],
                         kXAxisLabelFontKey : [UIFont fontWithName:@"TrebuchetMS" size:10],
                         kYAxisLabelColorKey : [UIColor colorWithRed:0.48 green:0.48 blue:0.49 alpha:0.4],
                         kYAxisLabelFontKey : [UIFont fontWithName:@"TrebuchetMS" size:10],
                         kYAxisLabelSideMarginsKey : @10,
                         kPlotBackgroundLineColorKye : [UIColor colorWithRed:0.48 green:0.48 blue:0.49 alpha:0.4]
                         };
}

- (void)addPlot:(SHPlot *)newPlot;{
    if(nil == newPlot) {
        return;
    }
    
    if(_plots == nil){
        _plots = [NSMutableArray array];
    }
    [_plots addObject:newPlot];
}

- (void)setupTheView{
    //线的数量_plots,点的数量plot
    for(SHPlot *plot in _plots) {
        [self drawPlotWithPlot:plot];
    }
}

#pragma mark - Actual Plot Drawing Methods

- (void)drawPlotWithPlot:(SHPlot *)plot {
    //点的数量
    self.dataNo = plot.plottingValues.count;
    //draw the grey lines
    [self drawHorizontalLine:plot];
    
    /*
     actual plot drawing
     */
    [self drawLineAndPlot:plot];
}

- (void)drawLineAndPlot:(SHPlot *)plot {
    
    NSDictionary *theme = plot.plotThemeAttributes;
    
    //背景
    CAShapeLayer *backgroundLayer = [CAShapeLayer layer];
    backgroundLayer.frame = self.bounds;
    backgroundLayer.fillColor = ((UIColor *)theme[kPlotFillColorKey]).CGColor;
    backgroundLayer.backgroundColor = [UIColor clearColor].CGColor;
    [backgroundLayer setStrokeColor:[UIColor clearColor].CGColor];
    [backgroundLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];
    
    CGMutablePathRef backgroundPath = CGPathCreateMutable();
    
    //圈
    CAShapeLayer *circleLayer = [CAShapeLayer layer];
    circleLayer.frame = self.bounds;
    circleLayer.fillColor = ((UIColor *)theme[kPlotPointFillColorKey]).CGColor;
    circleLayer.backgroundColor = [UIColor clearColor].CGColor;
    [circleLayer setStrokeColor:((UIColor *)theme[kPlotPointFillColorKey]).CGColor];
    [circleLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];
    
    CGMutablePathRef circlePath = CGPathCreateMutable();
    
    //线
    CAShapeLayer *graphLayer = [CAShapeLayer layer];
    graphLayer.frame = self.bounds;
    graphLayer.fillColor = [UIColor clearColor].CGColor;
    graphLayer.backgroundColor = [UIColor clearColor].CGColor;
    [graphLayer setStrokeColor:((UIColor *)theme[kPlotStrokeColorKey]).CGColor];
    [graphLayer setLineWidth:((NSNumber *)theme[kPlotStrokeWidthKey]).intValue];
    
    CGMutablePathRef graphPath = CGPathCreateMutable();
    
    plot.xPoints = calloc(sizeof(CGPoint), self.dataNo);
    //logic to fill the graph path, ciricle path, background path.
    [plot.plottingValues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSDictionary *dic = (NSDictionary *)obj;
        
        __block NSNumber *_key = nil;
        __block NSNumber *_value = nil;
        
        [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
            _key = (NSNumber *)key;
            _value = (NSNumber *)obj;
        }];
        
        //x value
        double y = self.frame.size.height * (1 -[_value doubleValue] / self.maxHeight);
        //第一个不用算-1
        double x = self.frame.size.width/(self.dataNo-1)*[_key doubleValue];
        plot.xPoints[_key.intValue] = CGPointMake(ceil(x), ceil(y));
    }];
    
    //起始位置
    CGPathMoveToPoint(graphPath, NULL, 0, plot.xPoints[0].y);
    CGPathMoveToPoint(backgroundPath, NULL, 0, plot.xPoints[0].y);
    
    //非起始位置
    for(int i=0; i< self.dataNo; i++){
        CGPoint point = plot.xPoints[i];
        CGPathAddLineToPoint(graphPath, NULL, point.x, point.y);
        if (i!=0 && i!=self.dataNo-1) CGPathAddEllipseInRect(circlePath, NULL, CGRectMake(point.x - 5, point.y - 5, 10, 10));
        CGPathAddLineToPoint(backgroundPath, NULL, point.x, point.y);
    }

    //以往的点+三点一面
    //一点
//    CGPathAddLineToPoint(graphPath, NULL, self.frame.size.width, self.frame.size.height);
    CGPathAddLineToPoint(backgroundPath, NULL, self.frame.size.width, self.frame.size.height);
    //两点
//    CGPathAddLineToPoint(graphPath, NULL,  0, self.frame.size.height);
    CGPathAddLineToPoint(backgroundPath, NULL, 0, self.frame.size.height);
    
    //三点
//    CGPathAddLineToPoint(graphPath, NULL, 0, self.frame.size.height);
    CGPathAddLineToPoint(backgroundPath, NULL, 0, self.frame.size.height);
    CGPathCloseSubpath(backgroundPath);
    
    backgroundLayer.path = backgroundPath;
    graphLayer.path = graphPath;
    circleLayer.path = circlePath;
    
    //动画
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration = 1;
    animation.fromValue = @(0.0);
    animation.toValue = @(1.0);
    [graphLayer addAnimation:animation forKey:@"strokeEnd"];
    
    backgroundLayer.zPosition = 0;
    graphLayer.zPosition = 1;
    circleLayer.zPosition = 2;
    
    [self.layer addSublayer:graphLayer];
    [self.layer addSublayer:circleLayer];
    [self.layer addSublayer:backgroundLayer];
    
    //点击按钮
    for(int i=1; i< self.dataNo-1; i++){
        CGPoint point = plot.xPoints[i];
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.backgroundColor = [UIColor clearColor];
        btn.tag = i;
        CGFloat radius = self.btRadius>0?self.btRadius:10;
        btn.frame = CGRectMake(point.x - radius, point.y - radius, 2*radius, 2*radius);
        [btn addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
        objc_setAssociatedObject(btn, kAssociatedPlotObject, plot, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        
        [self addSubview:btn];
    }
}

/**draw Level,绘置水平线,横线*/
- (void)drawHorizontalLine:(SHPlot *)plot {
    
    //Y水平线,横线
    CAShapeLayer *linesLayer = [CAShapeLayer layer];
    linesLayer.frame = self.bounds;
    linesLayer.fillColor = [UIColor clearColor].CGColor;
    linesLayer.backgroundColor = [UIColor clearColor].CGColor;
    linesLayer.strokeColor = ((UIColor *)_themeAttributes[kPlotBackgroundLineColorKye]).CGColor;
    linesLayer.lineWidth = 1;
    
    CGMutablePathRef linesPath = CGPathCreateMutable();
    
    double intervalInPx = self.frame.size.height / self.horizontalLineNo;
    for(NSInteger i= self.horizontalLineNo + 1; i > 0; i--){
        //当前点
        CGPoint currentLinePoint = CGPointMake(0, (i * intervalInPx));
        //划线
        //起始点
        CGPathMoveToPoint(linesPath, NULL, currentLinePoint.x, currentLinePoint.y);
        //终点
        CGPathAddLineToPoint(linesPath, NULL, currentLinePoint.x, currentLinePoint.y);
    }
    
    linesLayer.path = linesPath;
    [self.layer addSublayer:linesLayer];
    
}

#pragma mark - UIButton event methods
//按钮事件
- (void)clicked:(id)sender{
    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 120, 30)];
    lbl.backgroundColor = [UIColor clearColor];
    UIButton *btn = (UIButton *)sender;
    NSUInteger tag = btn.tag;
    
    SHPlot *_plot = objc_getAssociatedObject(btn, kAssociatedPlotObject);
    NSString *text = [_plot.plottingPointsLabels objectAtIndex:tag];
    
    lbl.text = text;
    lbl.textColor = [UIColor whiteColor];
    lbl.textAlignment = NSTextAlignmentCenter;
    lbl.font = (UIFont *)_plot.plotThemeAttributes[kPlotPointValueFontKey];
    [lbl sizeToFit];
    lbl.frame = CGRectMake(0, 0, lbl.frame.size.width + 5, lbl.frame.size.height);
    
    CGPoint point =((UIButton *)sender).center;
    point.y -= 15;
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [PopoverView showPopoverAtPoint:point
                                 inView:self
                        withContentView:lbl
                               delegate:nil];
    });
}

#pragma mark - Theme Key Extern Keys

NSString *const kXAxisLabelColorKey         = @"kXAxisLabelColorKey";
NSString *const kXAxisLabelFontKey          = @"kXAxisLabelFontKey";
NSString *const kYAxisLabelColorKey         = @"kYAxisLabelColorKey";
NSString *const kYAxisLabelFontKey          = @"kYAxisLabelFontKey";
NSString *const kYAxisLabelSideMarginsKey   = @"kYAxisLabelSideMarginsKey";
NSString *const kPlotBackgroundLineColorKye = @"kPlotBackgroundLineColorKye";

@end
